using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using X3DXNA.hud;

namespace X3DXNA.core.Controllers
{
    public class InputController : Microsoft.Xna.Framework.GameComponent
    {
        ViewPointController viewPointController;
        ShapeController shapeController;
        KeyboardState newKeyboardState, oldKeyboardState;
        MouseState newMouseState, oldMouseState;
        HUD hud;
        Vector2 _mousePosition;
        Core core;

        public Vector2 mousePosition { get { return _mousePosition; } }
        public bool leftMouseButtonPressed { get; set; }

        public InputController(Game game, Core core, ViewPointController viewPointController, ShapeController shapeController, HUD hud)
            : base(game)
        {
            game.Components.Add(this);
            this.viewPointController = viewPointController;
            this.shapeController = shapeController;
            this.hud = hud;
            this._mousePosition = new Vector2();
            this.core = core;
        }

        public override void Initialize()
        {
            oldKeyboardState = Keyboard.GetState();
            base.Initialize();
        }

        public override void Update(GameTime gameTime)
        {
            core.stopWatch.Restart();

            Keys pressedKey = new Keys();
            newKeyboardState = Keyboard.GetState();
            newMouseState = Mouse.GetState();

            _mousePosition = new Vector2(newMouseState.X, newMouseState.Y);
            hud.setMousePosition = _mousePosition;
 
            foreach (Keys k in newKeyboardState.GetPressedKeys())
            {
                if (!oldKeyboardState.IsKeyDown(k))
                    pressedKey = k;
            }

            if (pressedKey == Keys.PageUp)
                viewPointController.nextCamera();

            if (pressedKey == Keys.PageDown)
                viewPointController.prevCamera();

            if (pressedKey == Keys.B)
                shapeController.drawBoundings = !shapeController.drawBoundings;

            if (pressedKey == Keys.I)
                hud.showHUD = !hud.showHUD;

            if (newMouseState.LeftButton == ButtonState.Released && oldMouseState.LeftButton == ButtonState.Pressed)
                leftMouseButtonPressed = true;
            else
                leftMouseButtonPressed = false;

            oldKeyboardState = newKeyboardState;
            oldMouseState = newMouseState;

            if (core.mouseIsOverATouchSensor())
                core.setCursor(System.Windows.Forms.Cursors.Hand);
            else
                core.setCursor(System.Windows.Forms.Cursors.Arrow);

            core.stopWatch.Stop();

            core.hud.InputControllerUpdate = core.stopWatch.ElapsedTicks.ToString();
            base.Update(gameTime);
        }

        public Ray getMouseRay(Game game, Matrix viewMatrix, Matrix projectionMatrix)
        {
            Vector3 nearSource = new Vector3(_mousePosition, 0f);
            Vector3 farSource = new Vector3(_mousePosition, 1f);

            Vector3 nearPoint = game.GraphicsDevice.Viewport.Unproject(nearSource,
                projectionMatrix, viewMatrix, Matrix.Identity);

            Vector3 farPoint = game.GraphicsDevice.Viewport.Unproject(farSource,
                projectionMatrix, viewMatrix, Matrix.Identity);

            Vector3 direction = farPoint - nearPoint;
            direction.Normalize();

            return new Ray(nearPoint, direction);
        }
    }
}
